/*
*  Impp - Instant Messenger
*
*  Copyright (C) 2008  Oliver Schneider
*
*  This program is free software; you can redistribute it and/or modify
*  it under the terms of the GNU General Public License as published by
*  the Free Software Foundation; either version 2 of the License, or
*  (at your option) any later version.
*
*  This program is distributed in the hope that it will be useful,
*  but WITHOUT ANY WARRANTY; without even the implied warranty of
*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
*  GNU General Public License for more details.
*
*  You should have received a copy of the GNU General Public License
*  along with this program; if not, write to the Free Software
*  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/
#include "CliPackage.h"
#include <wx/strconv.h>

namespace Impp {

CliPackage::CliPackage() :
	mem(),data(mem)
{
	data.BigEndianOrdered(true);
}

CliPackage::~CliPackage()
{
}

void CliPackage::setBigEndianOrdered(bool be){
	data.BigEndianOrdered(be);
}

void CliPackage::writeData(byte* d, size_t size){
	data.Write8(d,size);
	//for (size_t i = 0; i < size; ++i) {
	//	data.Write8(d[i]);
	//}	
}

void CliPackage::writeByte(byte b){
	data.Write8(b);
}

void CliPackage::writeWord(word w){
	data.Write16(w);
}


void CliPackage::writeDWord(dword dw){
	data.Write32(dw);
}

void CliPackage::writeQWord(qword qw){
	data.Write64(qw);
}

void CliPackage::writeString(const char* value, word lng){
	for (word i = 0; i < lng; ++i) {
		data.Write8(value[i]);
	}	
}



void CliPackage::writeString(const wxString & str){
	//tmp.Replace(wxT("\u20AC"), wxT("E"));
	wxCharBuffer buf = str.mb_str(wxConvISO8859_1);
	if(buf.data() == NULL){
		wxLogError(wxT("CliPackage::writeString: Coudn't write String, because it coudn't converted to ISO8859-1!"));
	}else{
		writeString(buf.data(),str.Len());
	}
}

void CliPackage::writeStringUTF8(const wxString & str){
	wxCharBuffer buf = str.ToUTF8();
	if(buf.data() == NULL){
		wxLogError(wxT("CliPackage::writeStringUTF8: Coudn't write String, because it coudn't converted to UTF8!"));
	}else{
		writeString(buf.data(),strlen(buf.data()));
	}

}

word CliPackage::getUTF8StringLng(const wxString & str){
	return strlen(str.ToUTF8());
}

void CliPackage::writeStringUTF16BE(const wxString & str){
	word lng = getUTF16BEStringLng(str);
	wxCharBuffer buf = str.mb_str(wxMBConvUTF16BE());
	if(buf.data() == NULL){
		wxLogError(wxT("CliPackage::writeStringUTF16BE: Coudn't write String, because it coudn't converted to UT16BE!"));
	}else{
		writeString(buf.data(),lng);
	}
	

}

word CliPackage::getUTF16BEStringLng(const wxString & str){
	size_t b = str.Len()*2;
	/*
	wxCharBuffer buf = str.mb_str(wxMBConvUTF16BE());
	if(buf.data()!=NULL){
		const char* pos = buf.data();
		size_t count = 0;
		while(*((word*)pos) != 0){
			pos++;
			count++;
		}
		wxLogDebug(wxT("Berechnet: %i, strlen: %i"), b,count );
	}
	*/
	return b;
}

void CliPackage::writeSnacHeader(word service, word subtype, word flags, dword requestId){
	writeWord(service);
	writeWord(subtype);
	writeWord(flags);
	writeDWord(requestId);
}

void CliPackage::writeTlv(word type, char* value, word valueLng){
	writeWord(type);
	writeWord(valueLng);
	writeString(value,valueLng);
}

void CliPackage::writeTlv(word type, CliPackage & data){
	writeTlvData(type,data.getData(),data.size());
}

void CliPackage::writeTlvString(word type, const wxString & value){
	writeWord(type);
	writeWord(value.Length());
	writeString(value);
}

void CliPackage::writeTlvData(word type, byte* value, word valueLng){
	writeWord(type);
	writeWord(valueLng);
	writeData(value,valueLng);
}

void CliPackage::writeTlvWord(word type, word data){
	writeWord(type);
	writeWord(word(0x02));
	writeWord(data);
}

void CliPackage::writeTlvByte(word type, byte data){
	writeWord(type);
	writeWord(word(0x01));
	writeByte(data);
}

void CliPackage::writeTlvEmpty(word type){
	writeWord(type);
	writeWord(0x0);
}

unsigned int CliPackage::size(){
	return 	mem.GetSize();
}

byte* CliPackage::getData(){
	return (byte*) 	mem.GetOutputStreamBuffer()->GetBufferStart();
}

void CliPackage::print(std::ostream & out){
	byte* b = getData();
	for (unsigned int i = 0; i <  mem.GetSize(); ++i) {
		toHex(out,b[i]);
		out << " ";
	}
	out << std::endl;
}

wxMemoryOutputStream* CliPackage::getOutputStream(){
	return &mem;
}

void CliPackage::writeSsiItem(Item* item){
	writeWord(item->itemName.Length());
	
	writeString(item->itemName);
	writeWord(item->groupId);
	writeWord(item->itemId);
	writeWord(item->typeOfItems);
	
	word itemDataLng = 0;
	
	for (word i = 0; i < item->data.size(); ++i) {
		itemDataLng+= 4; //tlv header
		itemDataLng+= item->data[i].length;
	}
	
	writeWord(itemDataLng);
	
	for (word i = 0; i < item->data.size(); ++i) {
		byte* tlvData = item->data[i].data;
		writeTlvData(item->data[i].type, tlvData, item->data[i].length);
	}
	
	
	
}

}
